package top.zhaoyuliu.logbook.client.compent;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import org.tio.client.ClientGroupContext;
import org.tio.core.ChannelContext;

import cn.hutool.cache.Cache;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import top.zhaoyuliu.logbook.client.builder.LbBuilder;
import top.zhaoyuliu.logbook.client.cache.WeakCache;

/**
 * Copyright © 2021 Arain. All rights reserved.
 *
 * @Title: AppenderCompent.java
 * @Prject: logbook-client
 * @Package: top.zhaoyuliu.logbook.client.compent
 * @Description: <功能详细描述>
 * @author: Arain
 * @date: 2021年1月22日 下午2:40:02
 * @version: V1.0
 */
public class AppenderCompent {

	private static String appId;

	private static Integer port = 0;

	private static ChannelContext clientChannelContext;

	private static Map<ClientGroupContext, Set<ChannelContext>> group = new ConcurrentHashMap<>();

	private static Set<String> excludePackages = new HashSet<>();

	public static Cache<String, Collection<LbBuilder>> weakCache = new WeakCache<>(DateUnit.SECOND.getMillis() * 30);

	public static Cache<String, Byte> typeCache = new WeakCache<>(DateUnit.SECOND.getMillis() * 30);

	public static Cache<String, ClientGroupContext> clientGroupContextCache = new WeakCache<>(
			DateUnit.SECOND.getMillis() * 30);

	public static Cache<String, List<Integer>> taskCountCache = new WeakCache<>(DateUnit.SECOND.getMillis() * 40);
	
	public static List<String> level = new ArrayList<>();

	public static String getAppId() {
		return appId;
	}

	public static Integer getPort() {
		return port;
	}

	public static void setPort(Integer app) {
		port = app;
	}

	public static ChannelContext getClientChannelContext() {
		return clientChannelContext;
	}

	public static void setAppId(String app) {
		appId = app;
	}

	public static void setClientChannelContext(ChannelContext channelContext) {
		clientChannelContext = channelContext;
	}

	public static void addExcludePackages(String... strings) {
		for (String string : strings) {
			excludePackages.add(string);
		}
	}

	public static Set<String> getExcludePackages() {
		return excludePackages;
	}

	public static void setClientGroupContext(ClientGroupContext clientGroupContext, Set<ChannelContext> groups) {
		group.put(clientGroupContext, groups);
	}

	public static Set<ChannelContext> getChannelContextByGroup(ClientGroupContext clientGroupContext) {
		return group.get(clientGroupContext).stream().filter(o -> !o.isClosed && !o.isRemoved)
				.collect(Collectors.toSet());
	}

	public static ClientGroupContext getGroup() {
		Set<ClientGroupContext> set = group.keySet();
		if (CollectionUtil.isEmpty(set)) {
			return null;
		}
		for (ClientGroupContext clientGroupContext : set) {
			return clientGroupContext;
		}
		return null;
	}

	public static ChannelContext choose() {
		if (getGroup() == null) {
			return null;
		}
		Set<ChannelContext> serverList = getChannelContextByGroup(getGroup()); // 获取所有的服务器列表
		ChannelContext chosen = Collections.min(serverList, new Comparator<ChannelContext>() {
			@Override
			public int compare(ChannelContext o1, ChannelContext o2) {
				if (o1.stat.latestTimeOfSentPacket > o2.stat.latestTimeOfSentPacket) {
					return 1;
				} else if (o1.stat.latestTimeOfSentPacket < o2.stat.latestTimeOfSentPacket) {
					return -1;
				}
				return 0;
			}
		});
		return chosen;

	}
}
